package com.example.net






import com.alibaba.android.arouter.launcher.ARouter
import com.bawei.net.BuildConfig

import com.blankj.utilcode.util.EncryptUtils
import com.google.gson.JsonObject
import com.tencent.mmkv.MMKV
import com.tencent.smtt.utils.Md5Utils
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import okio.Buffer
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

object HttpManager {

    private fun getOkHttpClient(type: HttpInterceptorType): OkHttpClient{
        //创建OKHttp的Builder对象
        var okHttpBuilder = OkHttpClient.Builder()

        //设置相关超时时间
        okHttpBuilder.connectTimeout(10, TimeUnit.SECONDS)
        okHttpBuilder.readTimeout(10, TimeUnit.SECONDS)
        okHttpBuilder.writeTimeout(10, TimeUnit.SECONDS)

        //设置日志拦截器
        if (BuildConfig.isOpenLog){
            okHttpBuilder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) //注意实际开发中不嫩在上线后打印日志
        }

        //设置自定义拦截器
        when(type){
            //通用拦截器
            HttpInterceptorType.COMMON -> {
                okHttpBuilder.addInterceptor(getTokenInterceptor())
            }

            //Token拦截器
            HttpInterceptorType.TOKEN -> {
                okHttpBuilder.addInterceptor(getTokenInterceptor())
            }

            //签名拦截器
            HttpInterceptorType.SIGN -> {
                okHttpBuilder.addInterceptor(getSignInterceptor())
            }

            //上传拦截器
            HttpInterceptorType.UPLOAD -> {
                okHttpBuilder.readTimeout(3, TimeUnit.MINUTES)
                okHttpBuilder.writeTimeout(3, TimeUnit.MINUTES)
            }
        }

        //设置服务器错误拦截器
        okHttpBuilder.addInterceptor(getServerErrorInterceptor())

        return okHttpBuilder.build()
    }

    private fun getRetrofit(type: HttpInterceptorType): Retrofit{
        return Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .client(getOkHttpClient(type))
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }


    /**
     * Token拦截器
     */
    private fun getTokenInterceptor(): Interceptor {
        return object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                try {
                    var token = MMKV.defaultMMKV().decodeString("token")
                    if (!token.isNullOrEmpty()){
                        var newRequest = chain.request().newBuilder().header("token", token).build()
                        var response = chain.proceed(newRequest)
                        //登录态过期
                        if (response.code == 403){
                            //跳转到登录页面
                            ARouter.getInstance().build("/activity/login").navigation()
                        }
                        return response
                    }
                    return chain.proceed(chain.request())
                } catch (e: Exception) {
                    return chain.proceed(chain.request())
                }
            }
        }
    }


    /**
     * 签名拦截器
     */
    private fun getSignInterceptor(): Interceptor {
        return object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var oldRequest = chain.request()
                try {
                    var builder = oldRequest.newBuilder()
                    builder.url(oldRequest.url)
                    builder.headers(oldRequest.headers)

                    //获取参数
                    var reqBody = oldRequest.body
                    var buf = Buffer()
                    reqBody?.writeTo(buf)
                    var bodyStr = buf.toString() //"{name:"zhangsan"}"
                    buf.close()
                    //截取JSON串
                    bodyStr = bodyStr.substring(bodyStr.indexOf("{"), bodyStr.lastIndexOf("}") + 1)
                    var reqJsonObj = JSONObject(bodyStr)

                    //提取JSON对象中字段
                    var sb = StringBuffer()
                    var keys = reqJsonObj.keys()
                    while (keys.hasNext()){
                        sb.append(reqJsonObj.getString(keys.next()))
                    }

                    //使用MD5加密
                    var signMD5 = getMd5Encrypt(sb.toString())
                    reqJsonObj.put("sign", signMD5)

                    //重新设置请求参数
                    var newJson = reqJsonObj.toString()
                    var newBody = newJson.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
                    builder.post(newBody)

                    //创建新的请求
                    var newRequest = builder.build()
                    return chain.proceed(newRequest)
                } catch (e: Exception) {
                    return chain.proceed(oldRequest)
                }
            }
        }
    }


    /**
     * 服务器发生错误时的拦截器
     */
    private fun getServerErrorInterceptor(): Interceptor {
        return object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var oldResponse = chain.proceed(chain.request())
                var builder = oldResponse.newBuilder()
                if (oldResponse.code >= 500){
                    var newJson = JSONObject()
                    newJson.put("statusCode", 500)
                    newJson.put("msg", "服务器接口异常，请联系客服！")
                    var newBody = newJson.toString().toResponseBody("application/json;charset=utf-8".toMediaTypeOrNull())
                    builder.body(newBody)
                }
                return builder.build()
            }
        }
    }


    /**
     * 对字符串进行Md5加密
     */
    private fun getMd5Encrypt(originStr: String): String{
        return EncryptUtils.encryptMD5ToString("${originStr}tamboo").lowercase() //其中“tamboo”串表示唯一标识，一般需要和后端约定
    }

    fun <T> createApiServer(clazz: Class<*>, type: HttpInterceptorType): T{
        return getRetrofit(type).create(clazz) as T
    }
}